package com.yt.order.api.client;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.yt.common.constant.Result;
import com.yt.common.enums.CodeEnum;
import com.yt.common.exception.BusinessException;
import com.yt.common.utils.StrUtils;
import com.yt.order.models.bo.*;
import com.yt.order.models.dto.WorkOrderInfoDTO;
import com.yt.order.models.service.IWorkOrderInfoService;
import com.yt.order.models.vo.EmployeeCommissionStatVO;
import com.yt.order.models.vo.WorkOrderInfoVO;
import com.yt.order.models.vo.WorkOrderStatisticVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 工单信息API控制器
 *
 * @author chen
 * @Date 2025-09-05 18:26:57
 */
@RestController
@RequestMapping("/api/workOrderInfo")
@Slf4j
@Api(value = "WorkOrderInfoApiController", tags = "工单信息Api接口")
public class WorkOrderInfoApiController {

    @DubboReference
    private IWorkOrderInfoService workOrderInfoService;

    /**
     * 添加工单信息
     */
    @PostMapping("/add")
    @ApiOperation(value = "添加工单信息", notes = "添加工单信息（返回新增的工单详情）")
    public Result<WorkOrderInfoVO> add(@RequestBody WorkOrderInfoSaveBO saveBO) {
        // 参数校验
        if (StrUtils.isEmpty(saveBO.getTitle()) || StrUtils.isEmpty(saveBO.getName())
                || StrUtils.isEmpty(saveBO.getPhone()) || saveBO.getType() == null
                || saveBO.getMoney() == null || saveBO.getMoney() <= 0) {
            return new Result<>(CodeEnum.FAIL_100002);
        }
        boolean success = workOrderInfoService.add(saveBO);
        if (success) {
            // 查询新增的工单信息
            WorkOrderInfoDTO dto = workOrderInfoService.selectOne(
                    new EntityWrapper<WorkOrderInfoDTO>()
                            .eq("title", saveBO.getTitle())
                            .eq("name", saveBO.getName())
                            .orderBy("create_time", false)
                            .last("LIMIT 1")
            );
            if (dto == null) {
                return new Result<>(CodeEnum.FAIL_100010);
            }
            WorkOrderInfoVO vo = new WorkOrderInfoVO();
            BeanUtils.copyProperties(dto, vo);
            return new Result<>(vo);
        }
        return new Result<>(CodeEnum.FAIL_100007);
    }

    /**
     * 更新工单信息
     */
    @PutMapping("/update/{id}")
    @ApiOperation(value = "更新工单信息", notes = "根据ID更新工单信息（返回更新后完整数据）")
    @ApiImplicitParam(name = "id", value = "工单ID", required = true, paramType = "path", dataType = "Long")
    public Result<WorkOrderInfoVO> update(@PathVariable("id") Long id, @RequestBody WorkOrderInfoSaveBO saveBO) {
        if (id == null) {
            return new Result<>(CodeEnum.FAIL_100002);
        }

        // 校验记录是否存在
        WorkOrderInfoDTO existingDto = workOrderInfoService.selectById(id);
        if (existingDto == null) {
            return new Result<>(CodeEnum.FAIL_100010);
        }

        // 复制非空属性
        WorkOrderInfoDTO updateDto = new WorkOrderInfoDTO();
        BeanUtils.copyProperties(saveBO, updateDto);
        updateDto.setId(id);
        updateDto.setRevision(existingDto.getRevision());

        boolean success = workOrderInfoService.updateById(updateDto);
        if (success) {
            WorkOrderInfoDTO updatedDto = workOrderInfoService.selectById(id);
            WorkOrderInfoVO vo = new WorkOrderInfoVO();
            BeanUtils.copyProperties(updatedDto, vo);
            return new Result<>(vo);
        }
        return new Result<>(CodeEnum.FAIL_100008);
    }

    /**
     * 切换工单状态
     */
    @PutMapping("/changeStatus/{id}")
    @ApiOperation(value = "切换工单状态", notes = "根据ID切换工单状态（返回更新后数据）")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "工单ID", required = true, paramType = "path", dataType = "Long"),
            @ApiImplicitParam(name = "status", value = "工单状态：0-未派单，1-进行中，2-已完成，3-已取消",
                    required = true, paramType = "query", dataType = "Integer")
    })
    public Result<WorkOrderInfoVO> changeStatus(
            @PathVariable Long id,
            @RequestParam Integer status) {

        // 业务校验
        if (status < 0 || status > 3) {
            return new Result<>(CodeEnum.FAIL_100002.getCode(), "状态值只能是0-3之间的整数");
        }

        WorkOrderInfoDTO dto = workOrderInfoService.selectById(id);
        if (dto == null) {
            return new Result<>(CodeEnum.FAIL_100010);
        }

        dto.setStatus(status);
        dto.setRevision(dto.getRevision()); // 携带乐观锁版本号
        boolean success = workOrderInfoService.updateById(dto);
        if (success) {
            WorkOrderInfoDTO updatedDto = workOrderInfoService.selectById(id);
            WorkOrderInfoVO vo = new WorkOrderInfoVO();
            BeanUtils.copyProperties(updatedDto, vo);
            return new Result<>(vo);
        }
        return new Result<>(CodeEnum.FAIL_100008);
    }

    /**
     * 删除工单信息
     */
    @DeleteMapping("/del/{id}")
    @ApiOperation(value = "删除工单信息", notes = "根据ID删除工单信息（仅未派单状态可删除）")
    @ApiImplicitParam(name = "id", value = "工单ID", required = true, paramType = "path", dataType = "Long")
    public Result<Void> delete(@PathVariable("id") Long id) {
        if (id == null) {
            return new Result<>(CodeEnum.FAIL_100002);
        }

        // 查询工单是否存在
        WorkOrderInfoDTO dto = workOrderInfoService.selectById(id);
        if (dto == null) {
            return new Result<>(CodeEnum.FAIL_100010); // 工单不存在
        }

        // 校验工单状态（仅未派单状态可删除）
        if (dto.getStatus() != 0) {
            return new Result<>(CodeEnum.FAIL_100011.getCode(), "仅未派单状态（0）的工单可删除");
        }

        // 执行删除
        boolean flag = workOrderInfoService.deleteById(id);
        return flag ? new Result<>() : new Result<>(CodeEnum.FAIL_100009);
    }

    /**
     * 按ID查询工单
     */
    @GetMapping("/get/{id}")
    @ApiOperation(value = "按ID查询工单", notes = "按ID查询工单详情（含关联信息）")
    @ApiImplicitParam(name = "id", value = "工单ID", required = true, paramType = "path", dataType = "Long")
    public Result<WorkOrderInfoVO> getById(@PathVariable("id") Long id) {
        if (id == null) {
            return new Result<>(CodeEnum.FAIL_100002);
        }
        WorkOrderInfoVO vo = workOrderInfoService.selectVoById(id);
        if (vo == null) {
            return new Result<>(CodeEnum.FAIL_100010);
        }
        return new Result<>(vo);
    }

    /**
     * 分页查询工单列表
     */
    @GetMapping("/list")
    @ApiOperation(value = "分页查询工单列表", notes = "查询所有符合条件的工单信息（分页）")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pageNo", value = "页码（默认1）", paramType = "query", dataType = "Integer"),
            @ApiImplicitParam(name = "pageSize", value = "每页条数（默认10）", paramType = "query", dataType = "Integer"),
            @ApiImplicitParam(name = "title", value = "工单标题（模糊匹配）", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "customerName", value = "客户名称（模糊匹配）", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "productName", value = "产品名称（模糊匹配）", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "status", value = "工单状态：0-未派单，1-进行中，2-已完成，3-已取消", paramType = "query", dataType = "Integer"),
            @ApiImplicitParam(name = "employeeId", value = "接单员ID", paramType = "query", dataType = "Long"),
            @ApiImplicitParam(name = "userId", value = "关联用户ID", paramType = "query", dataType = "Long"),
            @ApiImplicitParam(name = "startDate", value = "创建开始时间", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "endDate", value = "创建结束时间", paramType = "query", dataType = "String")
    })
    public Result<Page<WorkOrderInfoVO>> list(
            WorkOrderInfoBO bo,
            @RequestParam(defaultValue = "1") Integer pageNo,
            @RequestParam(defaultValue = "10") Integer pageSize) {
        if (pageNo < 1) pageNo = 1;
        if (pageSize < 1 || pageSize > 100) pageSize = 10;

        log.info("查询时间范围：startDate={}, endDate={}", bo.getStartDate(), bo.getEndDate());


        Page<WorkOrderInfoVO> page = new Page<>(pageNo, pageSize);
        Page<WorkOrderInfoVO> resultPage = workOrderInfoService.selectPageVo(page, bo);
        return new Result<>(resultPage);
    }

      /**
     * DTO转VO工具方法
     */
    private WorkOrderInfoVO convertToVO(WorkOrderInfoDTO dto) {
        WorkOrderInfoVO vo = new WorkOrderInfoVO();
        BeanUtils.copyProperties(dto, vo);
        return vo;
    }

    @PostMapping("/statistic")
    @ApiOperation(value = "工单统计", notes = "多条件组合查询")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "status", value = "工单状态：0-未派单，1-进行中，2-已完成，3-已取消（可选）",
                    paramType = "body", dataTypeClass = Integer.class),
            @ApiImplicitParam(name = "type", value = "工单类型：0-客户下单，1-系统自建（可选）",
                    paramType = "body", dataTypeClass = Integer.class),
            @ApiImplicitParam(name = "startTime", value = "统计开始时间",
                    paramType = "body", dataTypeClass = String.class),
            @ApiImplicitParam(name = "endTime", value = "统计结束时间",
                    paramType = "body", dataTypeClass = String.class)
    })
    public Result<WorkOrderStatisticVO> statistic(@RequestBody WorkOrderStatisticBO bo) {
        try {
            WorkOrderStatisticVO statistic = workOrderInfoService.statistic(bo);
            return new Result<>(statistic);
        } catch (BusinessException e) {
            return new Result<>(e.getCode(), e.getMessage());
        } catch (Exception e) {
            log.error("工单统计异常", e);
            return new Result<>(CodeEnum.FAIL_100001);
        }
    }

    @PostMapping("/filter")
    @ApiOperation(value = "工单筛选", notes = "按状态/类型/时间等条件筛选工单")
    public Result<List<WorkOrderInfoVO>> filter(@RequestBody WorkOrderFilterBO bo) {
        List<WorkOrderInfoVO> voList = workOrderInfoService.filterWorkOrders(bo);
        return new Result<>(voList);
    }



    @ApiOperation(value = "获取未派单工单列表", notes = "查询所有未派单状态的工单（状态为0）")
    @PostMapping("/unassigned/list")
    public Result<Page<WorkOrderInfoVO>> getUnassignedList(
            WorkOrderInfoBO bo,
            @RequestParam(defaultValue = "1") Integer pageNo,
            @RequestParam(defaultValue = "10") Integer pageSize) {

        if (pageNo < 1) pageNo = 1;
        if (pageSize < 1 || pageSize > 100) pageSize = 10;

        Page<WorkOrderInfoVO> page = new Page<>(pageNo, pageSize);
        Page<WorkOrderInfoVO> resultPage = workOrderInfoService.selectUnassignedPage(page, bo);
        return new Result<>(resultPage);
    }

    @ApiOperation(value = "手动派单", notes = "将未派单工单分配给接单员，状态改为进行中")
    @PostMapping("/dispatch")
    public Result dispatch(@RequestBody WorkOrderDispatchBO dispatchBO) {
        try {
            boolean success = workOrderInfoService.dispatch(dispatchBO);
            return success ? new Result<>() : new Result<>(CodeEnum.FAIL_100013);
        } catch (BusinessException e) {
            return new Result<>(e.getCode(), e.getMessage());
        }
    }

    @GetMapping("/stat/employeeCommission")
    @ApiOperation(value = "统计接单员工单数量及提成总数", notes = "按接单员ID和时间段统计")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "employeeId", value = "接单员ID", required = true, paramType = "query", dataType = "Long"),
            @ApiImplicitParam(name = "startTime", value = "开始时间（yyyy-MM-dd HH:mm:ss）", required = true, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "endTime", value = "结束时间（yyyy-MM-dd HH:mm:ss）", required = true, paramType = "query", dataType = "String")
    })
    public Result<EmployeeCommissionStatVO> statEmployeeCommission(
            @RequestParam Long employeeId,
            @RequestParam String startTime,
            @RequestParam String endTime) {
        try {
            // 时间格式转换
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Date start = sdf.parse(startTime);
            Date end = sdf.parse(endTime);
            EmployeeCommissionStatVO stat = workOrderInfoService.statEmployeeCommission(employeeId, start, end);
            return new Result<>(stat);
        } catch (ParseException e) {
            return new Result<EmployeeCommissionStatVO>(CodeEnum.FAIL_100002.getCode(), "时间格式错误");
        }
    }


    @PostMapping("/archiveAllCompleted")
    @ApiOperation(value = "一键归档", notes = "将所有已完成状态的工单转为已归档")
    public Result<Void> archiveAllCompleted() {
        boolean success = workOrderInfoService.archiveCompletedOrders();
        if (success) {
            return new Result<Void>();
        } else {
            return new Result<Void>(CodeEnum.FAIL_100012.getCode(), "归档失败，无符合条件的工单");
        }
    }
}